package com.song.boot.springstudy.ms.szjz.al5;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class PriceFetcher {
    // 第三方接口模拟
    private static final int MAX_CONCURRENT_REQUESTS = 5;
    private static final int REQUEST_INTERVAL_MS = 200; // 200ms间隔保证5个/秒
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private final ExecutorService executor = Executors.newFixedThreadPool(MAX_CONCURRENT_REQUESTS);
    private final AtomicInteger activeRequests = new AtomicInteger(0);
    private final BlockingQueue<RequestTask> requestQueue = new LinkedBlockingQueue<>();
    private long lastRequestTime = 0;

    // 内部请求任务类
    private class RequestTask {
        final String time;
        final int index;
        final CompletableFuture<Double> future;
        
        RequestTask(String time, int index, CompletableFuture<Double> future) {
            this.time = time;
            this.index = index;
            this.future = future;
        }
    }

    // 模拟第三方API调用
    private Double callThirdPartyAPI(String time) throws InterruptedException {
        // 模拟网络延迟 (100ms ~ 1000ms)
        // int delay = 100 + (int)(Math.random() * 900);
        int delay = 100 + (int)(Math.random() * 1000);
        Thread.sleep(delay);
        
        // 生成随机价格作为模拟结果
        return Double.parseDouble(String.format("%.2f", Math.random() * 100));
    }

    // 处理队列中的请求
    private void processQueue() {
        while (activeRequests.get() < MAX_CONCURRENT_REQUESTS && !requestQueue.isEmpty()) {
            long currentTime = System.currentTimeMillis();
            long elapsed = currentTime - lastRequestTime;
            
            if (elapsed < REQUEST_INTERVAL_MS) {
                scheduler.schedule(this::processQueue, REQUEST_INTERVAL_MS - elapsed, TimeUnit.MILLISECONDS);
                return;
            }
            
            RequestTask task = requestQueue.poll();
            if (task != null) {
                activeRequests.incrementAndGet();
                lastRequestTime = System.currentTimeMillis();
                
                executor.execute(() -> {
                    try {
                        Double price = callThirdPartyAPI(task.time);
                        task.future.complete(price);
                    } catch (Exception e) {
                        task.future.completeExceptionally(e);
                    } finally {
                        activeRequests.decrementAndGet();
                        processQueue(); // 处理下一个请求
                    }
                });
            }
        }
    }

    // 获取单个价格
    public CompletableFuture<Double> fetchPrice(String time) {
        CompletableFuture<Double> future = new CompletableFuture<>();
        requestQueue.add(new RequestTask(time, -1, future));
        processQueue();
        return future;
    }

    // 批量获取价格
    public List<Double> getPrices(List<String> times) {
        List<CompletableFuture<Double>> futures = new ArrayList<>();
        List<Double> results = new ArrayList<>(Collections.nCopies(times.size(), null));
        
        // 创建所有请求
        for (int i = 0; i < times.size(); i++) {
            final int index = i;
            CompletableFuture<Double> future = new CompletableFuture<>();
            requestQueue.add(new RequestTask(times.get(i), index, future));
            
            future.whenComplete((price, ex) -> {
                if (price != null) {
                    results.set(index, price);
                }
            });
            
            futures.add(future);
        }
        
        processQueue();
        
        try {
            // 等待所有完成或超时5秒
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                .exceptionally(ex -> null)
                .get(2, TimeUnit.SECONDS);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            // 超时后返回已获取的结果
        }
        
        return results;
    }

    // 关闭资源
    public void shutdown() {
        executor.shutdown();
        scheduler.shutdown();
    }

    public static void main(String[] args) {
        PriceFetcher fetcher = new PriceFetcher();
        
        List<String> times = Arrays.asList(
            "2023-01-01 08:00", "2023-01-01 08:01", "2023-01-01 08:02",
            "2023-01-01 08:03", "2023-01-01 08:04", "2023-01:04", "2023-01-01 08:05",
            "2023-01-01 08:06", "2023-01-01 08:07", "2023-01-01 08:08",
            "2023-01-01 08:09"
        );
        
        List<Double> results = fetcher.getPrices(times);
        
        System.out.println("最终结果:");
        for (int i = 0; i < times.size(); i++) {
            System.out.printf("%s: %s%n", times.get(i), 
                results.get(i) != null ? results.get(i) : "请求超时或失败");
        }
        
        fetcher.shutdown();
    }
}